#pragma once

#include <sstream>
#include "Object.h"
#include "SQLObject.h"
#include "SQLObjectImpl.h"
#include "SQLExpr.h"
#include "statement/SQLSelectOrderByItem.h"
class SQLASTVisitor;
class SQLOrderBy : virtual public SQLObjectImpl, virtual public SQLReplaceable
{

private:
  SQLObject_ptr parent;

  // http://stackoverflow.com/questions/1155142/why-do-i-get-an-error-in-forming-reference-to-reference-type-map
  // The map needs a copy of the string to store:
  std::shared_ptr<std::map<std::string, Object_ptr>> attributes;

  typedef SQLObject super;
  string_ptr buf;
  BOOL_ptr siblings;

protected:
  SQLSelectOrderByItem_list_ptr items;
  void accept0(SQLASTVisitor_ptr visitor);

public:
  SQLOrderBy();
  SQLOrderBy(SQLExpr_ptr expr);
  SQLOrderBy(SQLExpr_ptr expr, SQLOrderingSpecification_ptr type);
  virtual ~SQLOrderBy();

  SHAREDOBJECT(SQLOrderBy);
  void addItem(SQLSelectOrderByItem_ptr item);
  void addItem(SQLExpr_ptr item);
  void addItem(SQLExpr_ptr expr, SQLOrderingSpecification_ptr type);

  SQLSelectOrderByItem_list_ptr getItems();

  virtual SQLObject_ptr getParent();
  virtual void setParent(SQLObject_ptr parent);
  virtual std::shared_ptr<std::map<std::string, Object_ptr>> getAttributes();

  // virtual Object_ptr getAttribute(string_ptr name);

  // virtual void putAttribute(string_ptr name, Object_ptr value);

  virtual std::shared_ptr<std::map<std::string, Object_ptr>> getAttributesDirect();

  virtual void output(std::stringstream *buf);

  SQLSelectOrderByItem_ptr createItem();

  // int hashCode();
  bool equals(Object_ptr obj);

  // SQLOrderBy *clone();
  virtual SQLObject_ptr clone();
  BOOL_ptr isSiblings()
  {
    return this->siblings;
  }
  void setSiblings(BOOL_ptr siblings)
  {
    this->siblings = siblings;
  }
};
